#!/usr/bin/env python3
'''
通勤模型

定义预期的使用模式，且配置应可便利地变更

TODO 时间价格折算
TODO 省下了步行的时间
TODO 花费的驾驶时间（耗用）
'''

import abc


class RouteDaily:
    r'''
    每周日常通勤路由说明：
    周二、四至五：一个来回（目前回程系同事顺风车）
    周一和周三：一个来回，加一次转移
    假期另计
    '''

    def __init__(self) -> None:
        self.p = {  # 路途
            r'km-store': {
                r'bike': {
                    r'bicycle': {
                        r'distance': 8400,  # the longest, in km
                        r'spent': 42,  # in minute
                    },
                    r'motorcycle': {
                        r'distance': 9400,
                        r'spent': 19,
                    },
                },
                r'car': {
                    r'distance': 9100,
                    r'spent': 19,
                    r'cost': 3128,  # in Cent
                },
            },
            r'store-ackt27': {
                r'walk': {
                    r'distance': 947,
                    r'spent': 13,
                },
                r'bike': {
                    r'bicycle': {
                        r'distance': 947,
                        r'spent': 5,
                    },
                    r'motorcycle': {
                        r'distance': 885,
                        r'spent': 6,
                    },
                },
                r'car': {
                    r'distance': 959,
                    r'spent': 4,
                },
            },
            r'km-ackt27': {  # 家到ACKT
                r'bike': {
                    r'bicycle': {
                        r'distance': 9200,
                        r'spent': 46,
                    },
                    r'motorcycle': {
                        r'distance': 10000,
                        r'spent': 24,
                    },
                },
                r'car': {
                    r'distance': 11000,
                    r'spent': 21,
                },
            },
            r'store-hps': {
                r'car': {
                    r'distance': 13000,
                    r'spent': 16,
                    r'cost': 3122,
                },
            },
            r'ackt27-hps': {
                r'car': {
                    r'distance': 14000,
                    r'spent': 18,
                },
            },
            r'hps-cross': {
                r'bus': {
                    r'spent': 36,
                    r'cost': 3,
                },
            },
            r'cross-km': {
                r'walk': {
                    r'distance': 212,
                    r'spent': 3,
                },
            },
            r'hps-km': {
                r'car': {
                    r'distance': 6700,
                    r'spent': 22,
                },
            },
        }

    def spentByCar(self):
        # @deprecated
        in_minute = self.p[r'km-ackt27'][r'car'][r'spent'] * 2 * 3 +\
            (
                self.p[r'km-ackt27'][r'car'][r'spent'] +
                self.p[r'ackt27-hps'][r'car'][r'spent'] +
                self.p[r'hps-km'][r'car'][r'spent']) * 2

        return in_minute, r'minutes per week'


class Taxi:
    def __init__(self) -> None:
        return None

    def __repr__(self) -> str:
        return r'通过taxi通勤'

    def calcSpent(self):
        r = RouteDaily()

        in_minute = (r.p[r'km-store'][r'car'][r'spent'] + r.p[r'store-ackt27'][r'walk'][r'spent']) * 2 * 3 +\
            (
                r.p[r'km-store'][r'car'][r'spent'] +
                r.p[r'store-ackt27'][r'walk'][r'spent'] * 2 +
                r.p[r'store-hps'][r'car'][r'spent'] +
                r.p[r'hps-cross'][r'bus'][r'spent'] +
                r.p[r'cross-km'][r'walk'][r'spent']) * 2

        return (in_minute, r'minutes per week'), (in_minute / 60, r'hours per week')


class TaxiJack(Taxi):
    r'蹭车怪'

    def __init__(self) -> None:
        super().__init__()


class DriveSelf:
    r'驾车怪'

    def __repr__(self) -> str:
        return r'通过私家车通勤'

    def calcSpent(self):
        r = RouteDaily()

        in_minute = r.p[r'km-ackt27'][r'car'][r'spent'] * 2 * 3 +\
            (
                r.p[r'km-ackt27'][r'car'][r'spent'] +
                r.p[r'ackt27-hps'][r'car'][r'spent'] +
                r.p[r'hps-km'][r'car'][r'spent']) * 2

        return (in_minute, r'minutes per week'), (in_minute / 60, r'hours per week')


class FactorySimpleMethod:
    # @reference https://www.cnblogs.com/ppap/p/11103324.html

    @staticmethod
    def produce(name):
        if name == r'taxi':
            return Taxi()
        elif name == r'taxi-jack':
            return TaxiJack()
        elif name == r'drive-self':
            return DriveSelf()


class FactoryAbstractMethod:
    __metaclass__ = abc.ABCMeta

    @abc.abstractclassmethod
    def calcSpent(self):
        pass

    @abc.abstractclassmethod
    def calcCost(self):
        pass


class FactoryTaxi(FactoryAbstractMethod):
    pass


class FactoryTaxiJack(FactoryTaxi):
    def __init__(self) -> None:
        super().__init__()
        self.model = TaxiJack

    def calcSpent(self):
        return self.model().calcSpent()

    def calcCost(self):
        pass


class FactoryDriveSelf(FactoryAbstractMethod):
    def __init__(self) -> None:
        super().__init__()
        self.model = DriveSelf

    def calcSpent(self):
        return self.model().calcSpent()

    def calcCost(self):
        pass
